package cn.hyh.controller;

import cn.hyh.entity.User;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

import javax.jws.Oneway;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.beans.PropertyEditorSupport;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @auther :hyh
 * @desc :
 * @date :2020/2/27
 */

/** 1. @ExceptionHandler  @ModelAttribute  @ InitBinder 声明在此类中
 *     表示跨controller类共享，  即全局的。  都会执行 这几个类中的方法。
 *  2.多个类都使用@ControllerAdvice   可以使用@order 排序
 *  3.@ExceptionHandler  会查找第一个合适的进行调用 ，当  @oreder  最高，但没有最佳匹配异常时，
 *  4. 如果@ModelAttribute  @InitBinder 同时存在，先执行@modelAttribute
 *
 *  reder优先级高。
 *    @ModelAttribute and 、 @InitBinder   会按照顺序 一次调用
 */
@Controller
@RestControllerAdvice(basePackages = "cn.hyh.controller")
class GlobalExceptionHandler {

	/**@exception作用的方法参数：
	 *       1.  异常  2. request/response/session   3.WebRequest/NativeWebRequest(用于获取请求参数，httpservletrequst只能获取一次)
	 *       4. Locale   5.inputStream/outPutStream     6.
	 * @exception作用的方法返回值类型：
	 *       1.ModelAndView/Model/map(转为model)/view/string(string转为view)
	 *       2.@responseBody 作用的方法返回任意值都转为json对象
	 *       2.httpEntity/ResponseEntity    3.void(结果直接写入response中)
	 *
	 * @param request
	 * @param response
	 * @param ex
	 * @return
	 */
	@ExceptionHandler
	public User exception(HttpServletRequest request, HttpServletResponse response, Exception ex) {
		System.out.println("出错了");
		return new User("11", 11);
	}

	@ModelAttribute
	public void  testModelAttribute(){
		System.out.println("先执行全局的ModelAttribute");

	}

	  //全局处理异常。
	@InitBinder   //这里的参数 和controller一样。
	public  void  dateConvert(WebDataBinder binder,HttpServletRequest request){
		//WebDataBinder必须放第一个位置。 是系统给我们创建对象，handlerMethod 每一个参数，都会创建一个对应的binder
		System.out.println("先执行全局的modelAttribute");
           binder.registerCustomEditor(Date.class,new DateEditor());
	}


	 class DateEditor extends PropertyEditorSupport{
		 @Override
		 public void setAsText(String text) throws IllegalArgumentException {
			 setValue(convert(text));
		 }




		 private  final List<String> formarts = new ArrayList<>(4);

		 public DateEditor() {
			 formarts.add("yyyy-MM");
			 formarts.add("yyyy-MM-dd");
			 formarts.add("yyyy-MM-dd HH:mm");
			 formarts.add("yyyy-MM-dd HH:mm:ss");
		 }




		 public Date convert(String source) {
			 String value = source.trim();
			 if ("".equals(value))
			 {
				 return null;
			 }
			 if (source.matches("^\\d{4}-\\d{1,2}$"))
			 {
				 return parseDate(source, formarts.get(0));
			 }
			 else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$"))
			 {
				 return parseDate(source, formarts.get(1));
			 }
			 else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}$"))
			 {
				 return parseDate(source, formarts.get(2));
			 }
			 else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$"))
			 {
				 return parseDate(source, formarts.get(3));
			 }
			 else
			 {
				 throw new IllegalArgumentException("Invalid boolean value '" + source + "'");
			 }
		 }



		 public Date parseDate(String dateStr, String format)
		 {
			 Date date = null;
			 try
			 {

				 DateFormat dateFormat = new SimpleDateFormat(format);
				 date = dateFormat.parse(dateStr);
			 }
			 catch (Exception e)
			 {

			 }
			 return date;
		 }
	 }
}
